import os
import sys
from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QGridLayout,
                             QPushButton, QLabel, QLineEdit, QTextEdit,
                             QFileDialog, QGroupBox, QDateTimeEdit, QProgressBar,
                             QMessageBox)
from PyQt5.QtCore import Qt, QDateTime, QThread, pyqtSignal
from docxtpl import DocxTemplate, InlineImage
from docx.shared import Cm
from PIL import Image
from datetime import datetime
import jinja2
import re
from win32com.client import DispatchEx  # 使用独立的Word实例
import pythoncom
import time

import pandas as pd
# 读取excel文件

def resource_path(relative_path):
    """获取资源的绝对路径"""
    if hasattr(sys, '_MEIPASS'):
        base_path = sys._MEIPASS
    else:
        base_path = os.path.abspath(".")
    return os.path.join(base_path, relative_path)

# 读取excel文件
# _current_dir = os.path.dirname(os.path.abspath(__file__))
# _path = os.path.join(_current_dir, 'static', 'config.xlsx')
df = pd.read_excel(resource_path("static/config.xlsx"))  # 替换为你的文件路径和文件名

class WordGenerationThread(QThread):
    update_progress = pyqtSignal(int, str)
    finished = pyqtSignal(bool, str)

    def __init__(self, template_path, context, output_path, image_folder, image_list):
        super().__init__()
        self.template_path = template_path
        self.context = context
        self.output_path = output_path
        self.image_folder = image_folder
        self.cancel_flag = False
        self.img_list = image_list  # 选择的文件夹图片数据

    def run(self):
        try:
            # 加载模板文件
            doc = DocxTemplate(self.template_path)

            _mx_list = self.context['qx_infos']['mx_list']
            _nimg = []
            for item in _mx_list:
                _nitem = item
                _inline_img1 = InlineImage(doc, item['full_img'], width=Cm(7), height=Cm(7))
                _inline_img2 = InlineImage(doc, item['jb_img'], width=Cm(7), height=Cm(7))
                _nitem['full_img'] = _inline_img1
                _nitem['jb_img'] = _inline_img2
                _nimg.append(_nitem)

            self.context['qx_infos']['mx_list'] = _nimg

            # 处理通道树障图片
            _sz_mx_list = self.context['sz_infos']['mx_list']
            _sz_nimg = []
            for item in _sz_mx_list:
                _sz_item = item
                _inline_img1 = InlineImage(doc, item['full_img'], width=Cm(7), height=Cm(7))
                _inline_img2 = InlineImage(doc, item['jb_img'], width=Cm(7), height=Cm(7))
                _sz_item['full_img'] = _inline_img1
                _sz_item['jb_img'] = _inline_img2
                _sz_nimg.append(_sz_item)

            self.context['sz_infos']['mx_list'] = _sz_nimg

            # 收集图片信息
            self.update_progress.emit(10, "正在收集图片信息...")
            image_files = []
            for root, dirs, files in os.walk(self.image_folder):
                for file in files:
                    if file.lower().endswith(('.jpg', '.jpeg', '.png')):
                        full_path = os.path.join(root, file)
                        try:
                            with Image.open(full_path) as img:
                                width, height = img.size
                                image_files.append({
                                    'path': full_path,
                                    'name': file,
                                    'folder': os.path.basename(root),
                                    'width': width,
                                    'height': height,
                                    'size': f"{width}×{height}"
                                })
                        except Exception as e:
                            self.update_progress.emit(0, f"无法读取图片 {file}: {str(e)}")

            if not image_files:
                self.finished.emit(False, "未找到任何图片文件")
                return

            self.context['images'] = image_files
            self.update_progress.emit(30, f"共找到 {len(image_files)} 张图片")

            # 渲染文档
            self.update_progress.emit(50, "正在生成Word文档...")
            doc.render(self.context, jinja_env=jinja2.Environment(autoescape=True))

            # 保存文档
            self.update_progress.emit(80, "正在保存文档...")
            doc.save(self.output_path)

            #     使用win32更新文档的域
            self.update_toc_and_fields(self.output_path)

            self.update_progress.emit(100, "文档生成完成!")
            self.finished.emit(True, f"成功生成Word文档: {self.output_path}")

        except Exception as e:
            self.finished.emit(False, f"生成文档时出错: {str(e)}")

    def cancel(self):
        self.cancel_flag = True

    def update_toc_and_fields(self, output_path):

        pythoncom.CoInitialize()
        word = None
        try:
            word = DispatchEx("Word.Application")
            word.Visible = False

            doc = word.Documents.Open(output_path)

            # 1. 备份目录样式
            if doc.TablesOfContents.Count > 0:
                toc = doc.TablesOfContents(1)
                # original_style = toc.Range.Style  # 保存原样式

                # 2. 更新时禁用样式自动更新
                # word.Options.UpdateStyleOnUpdate = False  # 关键设置
                toc.UpdatePageNumbers()  # 仅更新页码

                # 3. 恢复原始样式
                # toc.Range.Style = original_style

            # 更新其他域（不影响目录）
            # doc.Fields.Update()
            doc.Save()

        except Exception as e:
            print(f"错误: {e}")
        finally:
            if word:
                word.Quit()
            pythoncom.CoUninitialize()


class WordGenerator(QWidget):
    def __init__(self):
        super().__init__()
        self.img_list = []
        self.worker = None
        self.initUI()
        self.load_default_template()

    def initUI(self):
        layout = QVBoxLayout()

        # 模板选择部分
        template_group = QGroupBox("模板设置")
        template_layout = QHBoxLayout()

        self.template_path = QLineEdit()
        self.template_path.setPlaceholderText("请选择Word模板文件(.docx)")
        template_btn = QPushButton("选择模板")
        template_btn.clicked.connect(self.select_template)

        template_layout.addWidget(self.template_path)
        template_layout.addWidget(template_btn)
        template_group.setLayout(template_layout)

        # 图片文件夹选择部分
        folder_group = QGroupBox("图片文件夹")
        folder_layout = QHBoxLayout()

        self.image_folder = QLineEdit()
        self.image_folder.setPlaceholderText("请选择包含图片的文件夹")
        folder_btn = QPushButton("选择文件夹")
        folder_btn.clicked.connect(self.select_image_folder)

        folder_layout.addWidget(self.image_folder)
        folder_layout.addWidget(folder_btn)
        folder_group.setLayout(folder_layout)

        # 巡检信息输入部分
        info_group = QGroupBox("巡检信息")
        info_layout = QGridLayout()

        # 第一行
        info_layout.addWidget(QLabel("省份:"), 0, 0)
        self.province = QLineEdit()
        self.province.setPlaceholderText("例如: 河南省")
        info_layout.addWidget(self.province, 0, 1)

        info_layout.addWidget(QLabel("供电单位:"), 1, 0)
        self.power_unit = QLineEdit()
        self.power_unit.setPlaceholderText("例如: 金水区供电所")
        info_layout.addWidget(self.power_unit, 1, 1)

        info_layout.addWidget(QLabel("供电公司:"), 2, 0)
        self.power_company = QLineEdit()
        self.power_company.setPlaceholderText("例如: 金水区")
        info_layout.addWidget(self.power_company, 2, 1)

        # 第二行 - 时间区间
        info_layout.addWidget(QLabel("巡检开始时间:"), 3, 0)
        self.start_time = QDateTimeEdit()
        self.start_time.setDateTime(QDateTime.currentDateTime())
        self.start_time.setCalendarPopup(True)
        self.start_time.setDisplayFormat("yyyy-MM-dd HH:mm")
        info_layout.addWidget(self.start_time, 3, 1)

        info_layout.addWidget(QLabel("巡检结束时间:"), 4, 0)
        self.end_time = QDateTimeEdit()
        self.end_time.setDateTime(QDateTime.currentDateTime())
        self.end_time.setCalendarPopup(True)
        self.end_time.setDisplayFormat("yyyy-MM-dd HH:mm")
        info_layout.addWidget(self.end_time, 4, 1)

        # 第三行
        info_layout.addWidget(QLabel("巡检机型:"), 5, 0)
        self.inspect_model = QLineEdit()
        self.inspect_model.setPlaceholderText("例如: 大疆")
        info_layout.addWidget(self.inspect_model, 5, 1)

        info_layout.addWidget(QLabel("飞行高度:"), 6, 0)
        self.flight_height = QLineEdit()
        self.flight_height.setPlaceholderText("单位: 米")
        info_layout.addWidget(self.flight_height, 6, 1)

        info_group.setLayout(info_layout)

        # 输出文件设置
        output_group = QGroupBox("输出设置")
        output_layout = QHBoxLayout()

        self.output_path = QLineEdit()
        self.output_path.setPlaceholderText("请选择Word文档保存位置")
        output_btn = QPushButton("选择保存位置")
        output_btn.clicked.connect(self.select_output_path)

        output_layout.addWidget(self.output_path)
        output_layout.addWidget(output_btn)
        output_group.setLayout(output_layout)

        # 操作按钮
        btn_layout = QHBoxLayout()
        self.generate_btn = QPushButton("生成Word文档")
        self.generate_btn.clicked.connect(self.start_generation)
        self.cancel_btn = QPushButton("取消")
        self.cancel_btn.clicked.connect(self.cancel_generation)
        self.cancel_btn.setEnabled(False)

        btn_layout.addWidget(self.generate_btn)
        btn_layout.addWidget(self.cancel_btn)
        btn_layout.addStretch()

        # 进度条
        self.progress_bar = QProgressBar()
        self.progress_bar.setRange(0, 100)

        # 日志输出
        self.log_output = QTextEdit()
        self.log_output.setReadOnly(True)

        # 添加到主布局
        layout.addWidget(template_group)
        layout.addWidget(folder_group)
        layout.addWidget(info_group)
        layout.addWidget(output_group)
        layout.addLayout(btn_layout)
        layout.addWidget(self.progress_bar)
        layout.addWidget(self.log_output)

        self.setLayout(layout)
        self.setWindowTitle("Word文档生成工具")
        self.resize(800, 600)

        self.load_default_template()

    def load_default_template(self):
        # 这里可以加载一个内置的默认模板
        _current_dir = os.path.dirname(os.path.abspath(__file__))
        _path = os.path.join(_current_dir, 'static', 'template.docx')

        self.template_path.setText(_path)
        pass

    def select_template(self):
        path, _ = QFileDialog.getOpenFileName(
            self, "选择Word模板", "", "Word文件 (*.docx)")
        if path:
            self.template_path.setText(path)

    def select_image_folder(self):
        folder = QFileDialog.getExistingDirectory(self, "选择图片文件夹")
        if folder:
            self.image_folder.setText(folder)
            # 自动设置输出路径
            if not self.output_path.text():
                _base_name = os.path.basename(os.path.dirname(folder))
                default_name = f"{_base_name}巡检报告_{datetime.now().strftime('%Y%m%d_%H%M')}.docx"
                default_path = os.path.join(os.path.dirname(folder), default_name)
                self.output_path.setText(default_path)

            # 遍历文件夹
            for root, dirs, files in os.walk(folder):
                image_files = [f for f in files if f.lower().endswith(('.jpg', '.jpeg', '.png'))]
                if not image_files:
                    continue
                self.img_list = image_files




    def select_output_path(self):
        default_name = f"巡检报告_{datetime.now().strftime('%Y%m%d_%H%M')}.docx"
        path, _ = QFileDialog.getSaveFileName(
            self, "保存Word文档", default_name, "Word文件 (*.docx)")
        if path:
            self.output_path.setText(path)

    def validate_inputs(self):
        if not self.template_path.text() or not os.path.exists(self.template_path.text()):
            self.show_error("请选择有效的Word模板文件")
            return False

        if not self.image_folder.text() or not os.path.isdir(self.image_folder.text()):
            self.show_error("请选择有效的图片文件夹")
            return False

        if not self.province.text().strip():
            self.show_error("请输入省份")
            return False

        if not self.power_unit.text().strip():
            self.show_error("请输入供电单位")
            return False

        if self.start_time.dateTime() > self.end_time.dateTime():
            self.show_error("开始时间不能晚于结束时间")
            return False

        if not self.inspect_model.text().strip():
            self.show_error("请输入巡检机型")
            return False

        if not self.flight_height.text().strip() or not self.flight_height.text().isdigit():
            self.show_error("请输入有效的飞行高度(数字)")
            return False

        if not self.output_path.text():
            self.show_error("请选择输出文件路径")
            return False

        return True

    def show_error(self, message):
        QMessageBox.critical(self, "输入错误", message)

    def start_generation(self):
        if not self.validate_inputs():
            return
        try:



            # 处理巡视汇总报告
            _xl = os.path.basename(os.path.dirname(self.image_folder.text()))
            _total_count = 0
            _xl_map = {}

            _sub_dirs = []
            # 获取选择的可见光文件夹下的所有子文件夹
            for root, dirs, files in os.walk(self.image_folder.text()):
                if len(dirs) > 0 and len(files) == 0:
                    _sub_dirs = dirs


            # for i in range(len(self.img_list)):
            #     _item = self.img_list[i]
            #     _arr = _item.split('.')[0].split('#')
            #     # 拼接线路名称和塔号
            #     _xl_name = ''
            #     for j in range(len(_arr) - 1):
            #         _jitem = _arr[j]
            #         if j == len(_arr) - 2:
            #             _xl_name += _jitem
            #         else:
            #             _xl_name += _jitem + '#'
            #
            #     if _xl_name in _xl_map:
            #         _xl_map[_xl_name].append('#' + _arr[-1])
            #     else:
            #         _xl_map[_xl_name] = ['#' + _arr[-1]]

            for i in range(len(_sub_dirs)):
                _item = _sub_dirs[i]
                _arr = _item.split('.')[0].split('#')
                # 拼接线路名称和塔号
                _xl_name = ''
                for j in range(len(_arr) - 1):
                    _jitem = _arr[j]
                    if j == len(_arr) - 2:
                        _xl_name += _jitem
                    else:
                        _xl_name += _jitem + '#'

                if _xl_name in _xl_map:
                    _xl_map[_xl_name].append('#' + _arr[-1])
                else:
                    _xl_map[_xl_name] = ['#' + _arr[-1]]





            _xj_baseinfo = []
            _fx_total_count = 0
            _fx_total_num = 0

            for key in _xl_map:
                _value = _xl_map[key]
                _total_count += len(_value)
                if key != _xl:
                    _fx_total_num += 1
                    _fx_total_count += len(_value)
                _xj_baseinfo.append({'name': key, 'qj': _value[0] + '-' + _value[-1] if len(_value) > 1 else _value[0], 'count': len(_value), 'jx': self.inspect_model.text()})

            # 统计缺陷明细
            # 精细化缺陷统计

            _dirname = os.path.join(os.path.dirname(self.image_folder.text()), '缺陷图片')


            _yb_dir = os.path.join(_dirname, '一般')
            _yz_dir = os.path.join(_dirname, '严重')
            _wj_dir = os.path.join(_dirname, '危急')

            _yb_img_list = []
            _yz_img_list = []
            _wj_img_list = []

            for root, dirs, files in os.walk(_yb_dir):
                _yb_img_list = [f for f in files if f.lower().endswith(('.jpg', '.jpeg', '.png'))]
            for root, dirs, files in os.walk(_yz_dir):
                _yz_img_list = [f for f in files if f.lower().endswith(('.jpg', '.jpeg', '.png'))]
            for root, dirs, files in os.walk(_wj_dir):
                _wj_img_list = [f for f in files if f.lower().endswith(('.jpg', '.jpeg', '.png'))]

            # 遍历三个文件下的图片 处理数据

            _yb_list = self.bl_image_list(_yb_img_list)
            _yz_list = self.bl_image_list(_yz_img_list)
            _wj_list = self.bl_image_list(_wj_img_list)
            _mx_list = self.bl_image_list_constain_2(_yb_img_list, _yz_img_list, _wj_img_list, _dirname)

            _sz_list, _szmx_list = self.bl_image_list_sz(_yb_img_list, _yz_img_list, _wj_img_list, _dirname)

            _sz_yb_count = 0
            _sz_yz_count = 0
            _sz_wj_count = 0

            for i in range(len(_sz_list)):
                _item = _sz_list[i]
                if _item['risk_level'] == '一般':
                    _sz_yb_count += 1
                if _item['risk_level'] == '严重':
                    _sz_yz_count += 1
                if _item['risk_level'] == '危急':
                    _sz_wj_count += 1

            # 缺陷
            _qx_infos = {'jxhqxtj': {'yb': len(_yb_img_list), 'yz': len(_yz_img_list), 'wj': len(_wj_img_list), 'total': len(_yb_img_list) + len(_yz_img_list) + len(_wj_img_list)},
                        'wj_list': _wj_list,
                        'yz_list': _yz_list,
                        'yb_list': _yb_list,
                        'mx_list': _mx_list}


            # 树障
            _sz_infos = {'hz_list': _sz_list, 'mx_list': _szmx_list}

            # 汇总报告
            _hz = {'zx_count': len(_xl_map[_xl]) if _xl in _xl_map else 0,
                   'fx_num': _fx_total_num,
                   'fx_count': _fx_total_count,
                   'qx_count': len(_yb_list) + len(_yz_list) + len(_wj_list),
                   'yb_count': len(_yb_list),
                   'yz_count': len(_yz_list),
                   'wj_count': len(_wj_list),
                   'sz_count': len(_sz_list),
                   'sz_yb_count': _sz_yb_count,
                   'sz_yz_count': _sz_yz_count,
                   'sz_wj_count': _sz_wj_count}


            # 准备模板上下文数据
            context = {
                'xl': _xl,
                'total_count': _total_count,
                'hz': _hz,
                'province': self.province.text(),
                'power_unit': self.power_unit.text(),
                'power_company': self.power_company.text(),
                'start_time': self.start_time.dateTime().toString("yyyy年MM月dd日"),
                'end_time': self.end_time.dateTime().toString("yyyy年MM月dd日"),
                'inspect_model': self.inspect_model.text(),
                'flight_height': self.flight_height.text(),
                'generate_time': datetime.now().strftime("%Y年%m月%d日 %H:%M"),
                'xj_baseinfo': _xj_baseinfo,
                'qx_infos': _qx_infos,
                'sz_infos': _sz_infos
            }

            # 创建并启动工作线程
            self.worker = WordGenerationThread(
                self.template_path.text(),
                context,
                self.output_path.text(),
                self.image_folder.text(),
                self.img_list,
            )

            self.worker.update_progress.connect(self.update_progress)
            self.worker.finished.connect(self.generation_finished)

            self.generate_btn.setEnabled(False)
            self.cancel_btn.setEnabled(True)
            self.log_output.clear()

            self.worker.start()
        except Exception as e:
            self.log_output.append(f"错误: 生成文档时出错 - {str(e)}")

    def cancel_generation(self):
        if self.worker and self.worker.isRunning():
            self.worker.cancel()
            self.log_output.append("正在取消生成过程...")
            self.cancel_btn.setEnabled(False)

    def update_progress(self, value, message):
        self.progress_bar.setValue(value)
        self.log_output.append(message)

    def generation_finished(self, success, message):
        self.progress_bar.setValue(100 if success else 0)
        self.log_output.append(message)

        self.generate_btn.setEnabled(True)
        self.cancel_btn.setEnabled(False)

        if success:
            QMessageBox.information(self, "完成", "Word文档生成成功!")

    def contains_substring(self, string, substrings):
        for substring in substrings:
            if substring in string:
                return True
        return False

    def bl_image_list_constain_2(self, yb_list, yz_list, wj_list, path_dir):
        keyword_column_data = df['树障隐患关键词']
        _keywords = keyword_column_data.dropna().values.tolist()

        _relist = []
        for i in range(len(wj_list)):
            _item = wj_list[i]
            # 过滤掉包含(2)的图片
            if '(2)' not in _item and self.contains_substring(_item, _keywords) is False:
                _device_map = self.split_power_device_name(_item)
                _device_map['full_img'] = os.path.join(os.path.join(path_dir, '危急'), _item)
                _device_map['jb_img'] = os.path.join(os.path.join(path_dir, '危急'), self.insert_before_jpg(_item))
                # 拼接线路名称和塔号
                if _device_map is not None:
                    _relist.append(_device_map)

        for i in range(len(yz_list)):
            _item = yz_list[i]
            # 过滤掉包含(2)的图片
            if '(2)' not in _item and self.contains_substring(_item, _keywords) is False:
                _device_map = self.split_power_device_name(_item)
                _device_map['full_img'] = os.path.join(os.path.join(path_dir, '严重'), _item)
                _device_map['jb_img'] = os.path.join(os.path.join(path_dir, '严重'), self.insert_before_jpg(_item))
                # 拼接线路名称和塔号
                if _device_map is not None:
                    _relist.append(_device_map)

        for i in range(len(yb_list)):
            _item = yb_list[i]
            # 过滤掉包含(2)的图片
            if '(2)' not in _item and self.contains_substring(_item, _keywords) is False:
                _device_map = self.split_power_device_name(_item)
                _device_map['full_img'] = os.path.join(os.path.join(path_dir, '一般'), _item)
                _device_map['jb_img'] = os.path.join(os.path.join(path_dir, '一般'), self.insert_before_jpg(_item))
                # 拼接线路名称和塔号
                if _device_map is not None:
                    _relist.append(_device_map)

        for i in range(len(_relist)):
            _item = _relist[i]
            _item['index'] = i + 1

        return _relist


    def bl_image_list_sz(self, yb_list, yz_list, wj_list, path_dir):

        keyword_column_data = df['树障隐患关键词']
        _keywords = keyword_column_data.dropna().values.tolist()
        # 树障汇总
        _hz_relist = []
        for i in range(len(wj_list)):
            _item = wj_list[i]
            # 过滤掉包含(2)的图片
            if '(2)' not in _item and self.contains_substring(_item, _keywords) is True:
                _device_map = self.split_power_device_name(_item)
                # 拼接线路名称和塔号
                if _device_map is not None:
                    _hz_relist.append(_device_map)

        for i in range(len(yz_list)):
            _item = yz_list[i]
            # 过滤掉包含(2)的图片
            if '(2)' not in _item and self.contains_substring(_item, _keywords) is True:
                _device_map = self.split_power_device_name(_item)
                # 拼接线路名称和塔号
                if _device_map is not None:
                    _hz_relist.append(_device_map)

        for i in range(len(yb_list)):
            _item = yb_list[i]
            # 过滤掉包含(2)的图片
            if '(2)' not in _item and self.contains_substring(_item, _keywords) is True:
                _device_map = self.split_power_device_name(_item)
                # 拼接线路名称和塔号
                if _device_map is not None:
                    _hz_relist.append(_device_map)

        # 树障明细
        _relist = []
        for i in range(len(wj_list)):
            _item = wj_list[i]
            # 过滤掉包含(2)的图片
            if '(2)' not in _item and self.contains_substring(_item, _keywords) is True:
                _device_map = self.split_power_device_name(_item)
                _device_map['full_img'] = os.path.join(os.path.join(path_dir, '危急'), _item)
                _device_map['jb_img'] = os.path.join(os.path.join(path_dir, '危急'), self.insert_before_jpg(_item))
                # 拼接线路名称和塔号
                if _device_map is not None:
                    _relist.append(_device_map)

        for i in range(len(yz_list)):
            _item = yz_list[i]
            # 过滤掉包含(2)的图片
            if '(2)' not in _item and self.contains_substring(_item, _keywords) is True:
                _device_map = self.split_power_device_name(_item)
                _device_map['full_img'] = os.path.join(os.path.join(path_dir, '严重'), _item)
                _device_map['jb_img'] = os.path.join(os.path.join(path_dir, '严重'), self.insert_before_jpg(_item))
                # 拼接线路名称和塔号
                if _device_map is not None:
                    _relist.append(_device_map)

        for i in range(len(yb_list)):
            _item = yb_list[i]
            # 过滤掉包含(2)的图片
            if '(2)' not in _item and self.contains_substring(_item, _keywords) is True:
                _device_map = self.split_power_device_name(_item)
                _device_map['full_img'] = os.path.join(os.path.join(path_dir, '一般'), _item)
                _device_map['jb_img'] = os.path.join(os.path.join(path_dir, '一般'), self.insert_before_jpg(_item))
                # 拼接线路名称和塔号
                if _device_map is not None:
                    _relist.append(_device_map)

        for i in range(len(_relist)):
            _item = _relist[i]
            _item['index'] = i + 1

        for i in range(len(_hz_relist)):
            _item = _hz_relist[i]
            _item['index'] = i + 1

        return _hz_relist, _relist

    def bl_image_list(self, img_list):
        keyword_column_data = df['树障隐患关键词']
        _keywords = keyword_column_data.dropna().values.tolist()
        _relist = []
        for i in range(len(img_list)):
            _item = img_list[i]
            # 过滤掉包含(2)的图片
            if '(2)' not in _item and self.contains_substring(_item, _keywords) is False:
                _device_map = self.split_power_device_name(_item)
                # 拼接线路名称和塔号
                if _device_map is not None:
                    _relist.append(_device_map)

        for i in range(len(_relist)):
            _item = _relist[i]
            _item['index'] = i + 1

        return _relist


    def insert_before_jpg(self, filename):
        """
        在.JPG扩展名前插入(2)

        参数:
            filename (str): 文件名，例如："10kV古塘线土桥支线旺坊次支线北岭林场2级次支线#053_真空断路器_绝缘保护壳缺失.附属设施_一般.JPG"

        返回:
            str: 处理后的文件名，例如："10kV古塘线土桥支线旺坊次支线北岭林场2级次支线#053_真空断路器_绝缘保护壳缺失.附属设施_一般(2).JPG"
        """
        try:
            # 使用正则表达式在.JPG前插入(2)
            new_filename = re.sub(r'\.(jpg|jpeg|png)$', r'(2).\1', filename, flags=re.IGNORECASE)
            return new_filename
        except Exception as e:
            print(f"文件名处理失败: {e}")
            return filename  # 如果出错返回原文件名


    def split_power_device_name(self, full_name):
        """
        分割电力设备名称字符串

        参数:
            full_name (str): 电力设备完整名称，例如："10kV古塘线土桥支线旺坊次支线北岭林场2级次支线#053_真空断路器_绝缘保护壳缺失.附属设施_一般.JPG"

        返回:
            dict: 包含分割后各部分的字典，键为：
                - voltage_level: 电压等级 (如 "10kV")
                - line_name: 线路全称 (如 "10kV古塘线土桥支线旺坊次支线北岭林场2级次支线")
                - pole_number: 杆塔编号 (如 "#053")
                - device_type: 设备类型 (如 "真空断路器")
                - problem: 问题描述 (如 "绝缘保护壳缺失.附属设施")
                - risk_level: 风险等级 (如 "一般")
        """

        try:
            # 去除文件扩展名
            name = re.sub(r'\.(jpg|jpeg|png)$', '', full_name, flags=re.IGNORECASE)

            # 使用正则表达式匹配各部分
            # pattern = r'^(?P<voltage_level>10kV)(?P<line_rest>.*?)(?P<pole_number>#\d+)_(?P<device_type>[^_]+)_(?P<problem>[^_]+)_(?P<risk_level>[^\.]+)$'
            pattern = r'^(?P<voltage_level>\d+kV)(?P<line_rest>.+?)(?P<pole_number>#\d+\+?\d*)_(?P<device_type>[^_]+)_(?P<problem>[^_]+)_(?P<risk_level>[^\.]+)$'

            match = re.match(pattern, name)

            if not match:
                raise ValueError("输入字符串格式不符合要求")

            _problems = match.group('problem').split('.')

            if len(_problems) > 1:
                # 组合各部分信息
                result = {
                    'voltage_level': match.group('voltage_level'),
                    'line_name': match.group('voltage_level') + match.group('line_rest'),
                    'pole_number': match.group('pole_number'),
                    'device_type': match.group('device_type'),
                    'problem': _problems[0],
                    'risk_level': match.group('risk_level')
                }
            else:
                # 组合各部分信息
                result = {
                    'voltage_level': match.group('voltage_level'),
                    'line_name': match.group('voltage_level') + match.group('line_rest'),
                    'pole_number': match.group('pole_number'),
                    'device_type': match.group('device_type'),
                    'problem': match.group('problem'),
                    'risk_level': match.group('risk_level')
                }


            return result

        except Exception as e:
            print(f"分割失败: {e}")
            return None